package com.sixbro.shiro.common.exception.handler;

import com.sixbro.shiro.common.exception.BizException;
import com.sixbro.shiro.common.exception.code.ApiResponseCode;
import com.sixbro.shiro.common.utils.ApiResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.AuthorizationException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.List;

/**
 * <p>
 *
 * </p>
 *
 * @Author: Mr.Lu
 * @Since: 2020/6/19 13:46
 */
@Slf4j
@RestControllerAdvice
public class RestExceptionHandler {

    /**
     * 系统繁忙，请稍候再试"
     *
     * @throws
     */
    @ExceptionHandler(Exception.class)
    public <T> ApiResult<T> handleException(Exception e) {
        log.error("Exception,exception:{}", e);
        return ApiResult.getResult(ApiResponseCode.SYSTEM_BUSY);
    }

    /**
     * 自定义全局异常处理
     *
     * @throws
     */
    @ExceptionHandler(value = BizException.class)
    public <T> ApiResult<T> businessExceptionHandler(BizException exception) {
        log.error("BusinessException,exception:{}", exception);
        return new ApiResult(exception.getMessageCode(), exception.getDetailMessage());
    }

    /**
     * 没有权限 返回403视图
     *
     * @return org.springframework.web.servlet.ModelAndView
     * @throws
     */
    @ExceptionHandler(value = AuthorizationException.class)
    public <T> ApiResult<T> erroPermission(AuthorizationException e) {
        log.error("BusinessException,exception:{}", e);
        return new ApiResult(ApiResponseCode.UNAUTHORIZED_ERROR);

    }

    /**
     * 处理validation 框架异常
     *
     * @throws
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public <T> ApiResult<T> methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
        log.error("methodArgumentNotValidExceptionHandler bindingResult.allErrors():{},exception:{}", e.getBindingResult().getAllErrors(), e);
        List<ObjectError> errors = e.getBindingResult().getAllErrors();
        return createValidExceptionResp(errors);
    }

    private <T> ApiResult<T> createValidExceptionResp(List<ObjectError> errors) {
        String[] msgs = new String[errors.size()];
        int i = 0;
        for (ObjectError error : errors) {
            msgs[i] = error.getDefaultMessage();
            log.info("msg={}", msgs[i]);
            i++;
        }
        return ApiResult.getResult(ApiResponseCode.METHODARGUMENTNOTVALIDEXCEPTION.getCode(), msgs[0]);
    }
}
